<?php
require_once 'Models/Admin/Service/AdminBaseService.php';

class AdminSessionService extends AdminBaseService {
	protected $expireSeconds = 1800;
	
	protected $gcProbability = 1;
	protected $gcDivisor = 100;
	
	public function createSession($userId, $sessionData = array()) {
		$this->collectGarbage();
		
		$userId = intval($userId);
		if ($userId <= 0) return null;
		
		$sessionDataString = $sessionData ? serialize($sessionData) : '';
		
		$sessionId = $this->generateSessionId();
		$this->getSessionDao()->add(array(
			'session_id' => $sessionId,
			'user_id' => $userId,
			'expire' => $this->getExpireTimestamp(),
			'session_data' => $sessionDataString,
		));
		return $sessionId;
	}
	
	public function getSession($sessionId) {
		$this->collectGarbage();
		
		if ('' == $sessionId) return null;
		
		$sessionInfo = $this->getSessionDao()->get($sessionId);
		if ($sessionInfo['expire'] <= time()) {
			$this->deleteSession($sessionId);
			return null;
		}
		$this->getSessionDao()->update($sessionId, array('expire' => $this->getExpireTimestamp()));
		
		$sessionInfo['session_data'] = $sessionInfo['session_data'] ? unserialize($sessionInfo['session_data']) : array();
		return $sessionInfo;
	}
	
	public function deleteSession($sessionId) {
		if ('' == $sessionId) return 0;
		return $this->getSessionDao()->delete($sessionId);
	}
	
	protected function collectGarbage() {
		$num = rand(1, $this->gcDivisor);
		if ($num <= $this->gcProbability) {
			$this->getSessionDao()->deletesByExpire(time());
		}
	}
	
	protected function getExpireTimestamp() {
		return time() + $this->expireSeconds;
	}
	
	/**
	 * @return string 32-character-string
	 */
	protected function generateSessionId() {
		$salt = "sdfdf*^\tFGFyWEId4\ra&2!cr3s56O1^";
		return md5($salt . uniqid('', true) . mt_rand());
	}
	
	/**
	 * @return AdminSessionDao
	 */
	protected function getSessionDao() {
		require_once 'Models/Admin/Dao/AdminDaoFactory.php';
		return AdminDaoFactory::getInstance()->createAdminSessionDao();
	}
}

